package com.letfox.auth.service.impl;

import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;

import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;

import com.letfox.auth.model.RegisterModel;
import com.letfox.auth.service.AuthService;
import com.letfox.common.enums.AuthEnum;
import com.letfox.common.enums.ValidateEnum;
import com.letfox.common.model.ResultResponse;
import com.letfox.common.util.ConvertTool;
import com.letfox.common.util.MD5Util;
import com.letfox.common.util.ServiceKeyUtil;
import com.letfox.common.util.UUIDHexGenerator;
import com.letfox.user.contants.AccountCacheContants;
import com.letfox.user.enums.AccountEnums.AccountAuthState;
import com.letfox.user.enums.AccountEnums.AccountState;
import com.letfox.user.enums.ContactEnums;
import com.letfox.user.enums.UserEnums.UserAuthState;
import com.letfox.user.enums.UserEnums.UserGender;
import com.letfox.user.enums.UserEnums.UserState;
import com.letfox.user.model.UAccount;
import com.letfox.user.model.UContact;
import com.letfox.user.model.UUser;
import com.letfox.user.model.query.AccountAuthorityQuery;
import com.letfox.user.model.relation.UAccountServiceKey;
import com.letfox.user.model.relation.UAccountUser;
import com.letfox.user.model.relation.UUserContact;
import com.letfox.user.service.AccountCacheService;
import com.letfox.user.service.AccountService;
import com.letfox.user.service.ContactService;
import com.letfox.user.service.UserService;
import com.letfox.user.service.query.AccountQueryService;
import com.letfox.user.service.relation.AccountServiceKeyService;
import com.letfox.user.service.relation.AccountUserService;
import com.letfox.user.service.relation.UserContactService;

@Service
@Transactional
public class AuthServiceImpl implements AuthService{
	
	private Logger logger = LoggerFactory.getLogger(getClass());
	
	@Autowired
	private UserService userService;
	@Autowired
	private AccountService accountService;
	@Autowired
	private AccountCacheService accountCacheService;
	@Autowired
	private AccountServiceKeyService accountServiceKeyService;
	@Autowired
	private AuthService authService;
	@Autowired
	private ContactService contactService;
	@Autowired
	private AccountUserService accountUserService;
	@Autowired
	private UserContactService userContactService;
	@Autowired
	private AccountQueryService accountQueryService;
	

	@Override
	public ResultResponse registerAccount(RegisterModel registerModel) {
		ResultResponse resultResponse = new ResultResponse();
		
		String checkAccount = registerModel.getAccount();
		String checkPassword = registerModel.getPassword();
		String checkMobilePhone = registerModel.getMobilePhone();
		
		//检验账号
		if(StringUtils.isBlank(checkAccount)){
			resultResponse.setStatusMessage(ValidateEnum.V100.getCode());
			resultResponse.setStatusMessage(ValidateEnum.V100.getMessage());
			return resultResponse;
		}
		//检验密码
		if(StringUtils.isBlank(checkPassword)){
			resultResponse.setStatusMessage(ValidateEnum.V102.getCode());
			resultResponse.setStatusMessage(ValidateEnum.V102.getMessage());
			return resultResponse;
		}
		//检验手机号码
		if(StringUtils.isBlank(checkMobilePhone)){
			resultResponse.setStatusMessage(ValidateEnum.V102.getCode());
			resultResponse.setStatusMessage(ValidateEnum.V102.getMessage());
			return resultResponse;
		}
		//检验账号 - 是否已注册
		UAccount accountInfo = accountService.getByAccount(checkAccount);
		if(accountInfo != null){
			resultResponse.setStatusMessage(ValidateEnum.V106.getCode());
			resultResponse.setStatusMessage(ValidateEnum.V106.getMessage());
			return resultResponse;
		}
		//检验手机号码 - 是否已注册
		UContact contact = contactService.getByTypeAndValue(ContactEnums.ContactType.MOBILE_PHONE.getValue(), checkMobilePhone);
		if(contact != null){
			resultResponse.setStatusMessage(ValidateEnum.V110.getCode());
			resultResponse.setStatusMessage(ValidateEnum.V110.getMessage());
			return resultResponse;
		}
		
		try{
			//创建用户
			UUser user = new UUser();
			//性别判断
			if(registerModel.getGender() == null || StringUtils.isBlank(registerModel.getGender())){
				user.setGender(UserGender.WOMAN.getValue());
			}else if(registerModel.getGender().equals(UserGender.MAN.getValue())){
				user.setGender(UserGender.MAN.getValue());
			}else if(registerModel.getGender().equals(UserGender.WOMAN.getValue())){
				user.setGender(UserGender.WOMAN.getValue());
			}
			user.setCreateTime(new Date());
			user.setUpdateTime(new Date());
			user.setUserId(UUIDHexGenerator.generator());
			//设置状态
			user.setState(UserState.STARTUP.getValue());
			user.setUserAuthState(UserAuthState.NO_AUTH.getValue());
			userService.save(user);
			
			//创建通讯记录
			contact = new UContact();
			contact.setContactId(UUIDHexGenerator.generator());
			contact.setContactType(ContactEnums.ContactType.MOBILE_PHONE.getValue());
			contact.setContactValue(checkMobilePhone);
			contact.setUpdateTime(new Date());
			contact.setCreateTime(new Date());
			contactService.save(contact);
			
			//用户通讯关联
			UUserContact userContact = new UUserContact();
			userContact.setCreateTime(new Date());
			userContact.setUpdateTime(new Date());
			userContact.setContactId(contact.getContactId());
			userContact.setUserId(user.getUserId());
			userContactService.save(userContact);
			
			//创建账号
			UAccount account = new UAccount();
			account.setRegisterTime(new Date());
			account.setUpdateTime(new Date());
			account.setAccountId(UUIDHexGenerator.generator());
			account.setAccount(checkAccount);
			account.setPassword(MD5Util.MD5(checkPassword));
			//设置状态
			account.setState(AccountState.STARTUP.getValue());
			account.setAccountAuthState(AccountAuthState.NO_ACTIVITY.getValue());
			accountService.save(account);
			
			//账号用户关联
			UAccountUser accountUser = new UAccountUser();
			accountUser.setAccountId(account.getAccountId());
			accountUser.setUserId(user.getUserId());
			accountUser.setCreateTime(new Date());
			accountUser.setUpdateTime(new Date());
			accountUserService.save(accountUser);
			
			resultResponse.setStatusCode(AuthEnum.R200.getCode());
			resultResponse.setStatusMessage(AuthEnum.R200.getMessage());
		}catch(Exception e){
			e.printStackTrace();
			logger.error(e.getMessage());
			TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
			resultResponse.setStatusCode(AuthEnum.R202.getCode());
			resultResponse.setStatusMessage(AuthEnum.R202.getMessage());
			return resultResponse;
		}
		return resultResponse;
	}

	@Override
	public ResultResponse authLogin(String account, String password) {
		ResultResponse resultResponse = new ResultResponse();
		
		String checkAccount = ConvertTool.toString(account);
		String checkPassword = ConvertTool.toString(password);
		//检验账号
		if(StringUtils.isBlank(checkAccount)){
			resultResponse.setStatusMessage(ValidateEnum.V100.getCode());
			resultResponse.setStatusMessage(ValidateEnum.V100.getMessage());
			return resultResponse;
		}
		//检验密码
		if(StringUtils.isBlank(checkPassword)){
			resultResponse.setStatusMessage(ValidateEnum.V102.getCode());
			resultResponse.setStatusMessage(ValidateEnum.V102.getMessage());
			return resultResponse;
		}
		
		//认证
		
		//账号服务缓存标识
		String cacheAccountServiceKeyID = AccountCacheContants.ACCOUNT_SERVICE_KEY + checkAccount;
		String accountServiceKey = null;
		try{
			//从缓存查找账号和服务KEY
			accountServiceKey = (String) accountCacheService.getAccountServiceKey(cacheAccountServiceKeyID);
			if(StringUtils.isBlank(accountServiceKey)){
				
				//后台数据库查找 - 账号信息
				UAccount accountInfo = accountService.getByAccount(checkAccount);
				
				//账号是否存在
				if(accountInfo == null){
					resultResponse.setStatusCode(ValidateEnum.V100.getCode());
					resultResponse.setStatusMessage(ValidateEnum.V100.getMessage());
					return resultResponse;
				}
				//再次检验密码
				if(!accountInfo.getPassword().equals(MD5Util.MD5(checkPassword))){
					resultResponse.setStatusCode(ValidateEnum.V101.getCode());
					resultResponse.setStatusMessage(ValidateEnum.V101.getMessage());
					return resultResponse; 
				}
				
				//后台数据库查找 - 账号服务KEY
				UAccountServiceKey serviceKey = accountServiceKeyService.getByAccountId(accountInfo.getAccountId());
				
				if(serviceKey == null){
					//新增服务KEY
					serviceKey = new UAccountServiceKey();
					serviceKey.setAccountId(accountInfo.getAccountId());
					serviceKey.setServiceKey(ServiceKeyUtil.createServiceKey());;
					serviceKey.setCreateTime(new Date());
					accountServiceKeyService.save(serviceKey);
				}else{
					//更新服务KEY
					serviceKey.setServiceKey(ServiceKeyUtil.createServiceKey());
					serviceKey.setCreateTime(new Date());
					accountServiceKeyService.update(serviceKey);
				}
				
				//添加缓存
				accountCacheService.addAccountServiceKey(cacheAccountServiceKeyID, serviceKey.getServiceKey());
				
				accountServiceKey = serviceKey.getServiceKey();
			}
		
		}catch(Exception e){
			e.printStackTrace();
			resultResponse.setData(accountServiceKey);
			resultResponse.setStatusCode(AuthEnum.A202.getCode());
			resultResponse.setStatusMessage(AuthEnum.A202.getMessage());
			return resultResponse;
		}
		
		//获取账号权限
		
		String cacheAccountAuthID= AccountCacheContants.ACCOUNT_AUTH + account;
		try{
			//先从缓存获取相关权限
			Map<String, Object> cacheAccountAuth = accountCacheService.getAccountAuth(cacheAccountAuthID);
			if(cacheAccountAuth.isEmpty()){
				Map<String, Object> condition = new HashMap<String, Object>();
				condition.put("account", account);
				//从后台获取账号权限列表
				List<AccountAuthorityQuery> accountAuthList = accountQueryService.getAuthorityListByParams(condition);
				Map<String,Object> accountAuth = new HashMap<String, Object>();
				for (AccountAuthorityQuery accountAuthorityQuery : accountAuthList) {
					accountAuth.put(accountAuthorityQuery.getAuthId(), accountAuthorityQuery.getAuthValue());
				}
				//添加缓存
				accountCacheService.addAccountAuth(cacheAccountAuthID, accountAuth);
			}
		}catch(Exception e){
			e.printStackTrace();
		}
		
		//设置存在过期时间
		accountCacheService.setExpire(cacheAccountServiceKeyID, 60 * 10, TimeUnit.SECONDS);
		accountCacheService.setExpire(cacheAccountAuthID, 60 * 10, TimeUnit.SECONDS);
		
		resultResponse.setData(accountServiceKey);
		resultResponse.setStatusCode(AuthEnum.A200.getCode());
		resultResponse.setStatusMessage(AuthEnum.A200.getMessage());
		return resultResponse;
	}

}

